<template>
  <div class="backup-container">

    <el-card class="backup-card">
      <div class="backup-header">
        <h2 class="backup-title">数据备份与恢复</h2>
        <p class="backup-subtitle">维护您的系统数据安全</p>
      </div>
      
      <div class="action-buttons">
        <el-button type="primary" class="action-button full-backup" @click="openFullBackupDialog">
          <div class="button-content">
            <el-icon class="button-icon"><Download /></el-icon>
            <div class="button-text">
              <span class="button-title">全量备份</span>
              <span class="button-desc">备份所有系统数据</span>
            </div>
          </div>
        </el-button>
        
        <el-button type="success" class="action-button incremental-backup" @click="openIncrementalBackupDialog">
          <div class="button-content">
            <el-icon class="button-icon"><DocumentCopy /></el-icon>
            <div class="button-text">
              <span class="button-title">增量备份</span>
              <span class="button-desc">仅备份有变更的数据</span>
            </div>
          </div>
        </el-button>
        
        <el-button type="warning" class="action-button restore-backup" @click="openRestoreBackupDialog">
          <div class="button-content">
            <el-icon class="button-icon"><RefreshRight /></el-icon>
            <div class="button-text">
              <span class="button-title">还原备份数据</span>
              <span class="button-desc">从备份文件中恢复数据</span>
            </div>
          </div>
        </el-button>
      </div>
      
      <div class="backup-footer">
        <el-alert
          title="数据安全提示"
          type="info"
          description="请定期进行数据备份，并将备份文件保存在安全位置。备份文件应使用强密码保护。"
          show-icon
          :closable="false"
        />
      </div>
    </el-card>


    <!-- 全量备份对话框 -->
    <el-dialog 
    v-model="fullBackupDialogVisible" 
    title="选择目标文件夹路径" 
    width="50%"
    :close-on-click-modal="false"
    
    >
        <FolderList 
        v-model:dir-path="dirPath" 
        v-model:folder-list="folderList" 
        @chose-folder="getFolderListOfHook"
        @back="backPath"
         />
         <template #footer>
          <el-button style="width: 100px;height: 40px;" @click="fullBackupDialogVisible = false">关闭</el-button>
          <rip-button @click="openFullBackupPasswordDialog" style="margin-left: 10px;width: 100px;height: 40px;">开始备份</rip-button>
         </template>
    </el-dialog>

    <!-- 全量备份 输入密码对话框 -->
    <el-dialog v-model="fullBackupPasswordDialogVisible" title="输入密码" width="50%">
      <el-input
      oninput = "value=value.replace(/[\u4e00-\u9fa5]+/g,'')" 
      minlength="6"
      maxlength="18"
      show-password 
      v-model="fullBackupPassword" 
      placeholder="请输入密码" 
      @blur="validateFullBackupPassword"
      />
      <template #footer>
        <el-button style="width: 100px;height: 40px;" @click="fullBackupPasswordDialogVisible = false">关闭</el-button>
        <rip-button @click="fullBackupOfHook" style="margin-left: 10px;width: 100px;height: 40px;">确定</rip-button>
      </template>
    </el-dialog>


      <!-- 增量备份对话框 -->
      <el-dialog 
        v-model="incrementalBackupDialogVisible" 
        title="选择目标文件夹路径" 
        width="50%"
        :close-on-click-modal="false"
      >
        <FolderList 
        v-model:dir-path="dirPath" 
        v-model:folder-list="folderList" 
        @chose-folder="getFolderListOfHook"
        @back="backPath"
         />
         <template #footer>
          <el-button style="width: 100px;height: 40px;" @click="incrementalBackupDialogVisible = false">关闭</el-button>
          <rip-button @click="openIncrementalBackupPasswordDialog" style="margin-left: 10px;width: 100px;height: 40px;">开始备份</rip-button>
         </template>
    </el-dialog>

    <!-- 增量备份 输入密码对话框 -->
    <el-dialog 
      v-model="incrementalBackupPasswordDialogVisible" 
      title="输入密码" 
      width="50%"
      :close-on-click-modal="false"
    >
      <el-input
      oninput = "value=value.replace(/[\u4e00-\u9fa5]+/g,'')" 
      minlength="6"
      maxlength="18"
      show-password 
      v-model="incrementalBackupPassword" 
      placeholder="请输入密码" 
      @blur="validateIncrementalBackupPassword"
      />
      <template #footer>
        <el-button style="width: 70px;height:43px;margin-right: 20px;" :disabled="incrementalBackupLoading" @click="incrementalBackupPasswordDialogVisible = false">关闭</el-button>
        <rip-button :loading="incrementalBackupLoading" @click="startIncrementalBackup">
          <span v-if="!incrementalBackupLoading">确定</span>
          <span v-else>备份中...</span>
        </rip-button>
      </template>
    </el-dialog>

    <!-- 备份进度弹窗 -->
    <el-dialog
      v-model="backupProgressVisible"
      title="备份进度"
      width="40%"
      :close-on-click-modal="false"
      :show-close="false"
    >
      <div class="backup-progress">
        <el-progress 
          :percentage="backupProgress" 
          :status="backupProgress === 100 ? 'success' : ''"
          :stroke-width="20"
          :format="percentageFormat"
        ></el-progress>
        <div class="progress-description">
          {{ backupProgressText }}
        </div>
      </div>
      <template #footer>
        <el-button v-if="backupProgress === 100" type="primary" @click="backupProgressVisible = false">完成</el-button>
      </template>
    </el-dialog>

    <!-- 还原备份数据对话框 -->
    <el-dialog 
      v-model="restoreBackupDialogVisible" 
      title="还原备份数据" 
      width="50%"
      :close-on-click-modal="false"
      :close-on-press-escape="!restoreLoading"
    >
      <div class="restore-form">
        <el-form label-position="top">
          <el-form-item label="压缩密码">
            <el-input 
              v-model="restoreBackupPassword" 
              show-password 
              placeholder="请输入备份压缩包密码" 
              :disabled="restoreLoading"
              prefix-icon="Lock"
            />
          </el-form-item>
          <el-form-item label="选择备份文件">
            <div class="file-upload-container">
              <el-upload
                class="backup-file-uploader"
                action="#"
                :auto-upload="false"
                :show-file-list="false"
                :on-change="handleFileChange"
                :disabled="restoreLoading"
              >
                <template #trigger>
                  <el-button type="primary" :disabled="restoreLoading">
                    <el-icon><Upload /></el-icon>
                    <span>选择文件</span>
                  </el-button>
                </template>
              </el-upload>
              <div v-if="selectedFile" class="selected-file">
                <el-icon><Document /></el-icon>
                <span class="file-name">{{ selectedFile.name }}</span>
                <span class="file-size">{{ formatFileSize(selectedFile.size) }}</span>
              </div>
              <div v-else class="file-placeholder">
                <el-icon><InfoFilled /></el-icon>
                <span>请选择ZIP格式的备份文件（最大1GB）</span>
              </div>
            </div>
          </el-form-item>
        </el-form>
      </div>

      <template #footer>
        <el-button 
          :disabled="restoreLoading" 
          @click="restoreBackupDialogVisible = false"
        >
          取消
        </el-button>
        <el-button 
          type="primary" 
          :loading="restoreLoading" 
          @click="startRestore"
          :disabled="!canRestore"
        >
          <span v-if="!restoreLoading">开始还原</span>
          <span v-else>还原中...</span>
        </el-button>
      </template>
    </el-dialog>

    <!-- 还原进度弹窗 -->
    <el-dialog
      v-model="restoreProgressVisible"
      title="备份还原进度"
      width="40%"
      :close-on-click-modal="false"
      :show-close="false"
    >
      <div class="backup-progress">
        <el-progress 
          :percentage="restoreProgress" 
          :status="restoreProgress === 100 ? 'success' : ''"
          :stroke-width="20"
          :format="percentageFormat"
        ></el-progress>
        <div class="progress-description">
          {{ restoreProgressText }}
        </div>
      </div>
      <template #footer>
        <el-button v-if="restoreProgress === 100" type="primary" @click="restoreProgressVisible = false">完成</el-button>
      </template>
    </el-dialog>
    
  </div>
</template>

<script setup lang="ts">
import { useBackup } from '@/hooks/server/useBackup'
import { ref, computed } from 'vue'
import { ElMessage } from 'element-plus'
import { Document, Upload, InfoFilled, Lock, Download, DocumentCopy, RefreshRight } from '@element-plus/icons-vue'

// 备份进度相关
const backupProgressVisible = ref(false)
const backupProgress = ref(0)
const backupProgressText = ref('正在准备增量备份...')
const incrementalBackupLoading = ref(false)

// 还原相关
const restoreProgressVisible = ref(false)
const restoreProgress = ref(0)
const restoreProgressText = ref('正在准备还原备份...')
const restoreLoading = ref(false)

// 格式化进度百分比
const percentageFormat = (percentage: number) => {
  return percentage === 100 ? '完成' : `${percentage}%`
}

// 格式化文件大小
const formatFileSize = (bytes: number): string => {
  if (bytes === 0) return '0 B'
  
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(1024))
  
  return `${(bytes / Math.pow(1024, i)).toFixed(2)} ${sizes[i]}`
}

const { 
   folderList,
   dirPath,
   getFolderListOfHook,
   backPath,

   // 全量备份
   fullBackupDialogVisible,
   openFullBackupDialog,

   // 全量备份 输入密码对话框
   fullBackupPasswordDialogVisible,
   fullBackupPassword,
   fullBackFlag,
   openFullBackupPasswordDialog,

   // 全量备份
   fullBackupOfHook,

   // 增量备份
   incrementalBackupDialogVisible,
   incrementalBackupPasswordDialogVisible,
   incrementalBackupPassword,
   incrementalBackupFlag,
   openIncrementalBackupDialog,
   openIncrementalBackupPasswordDialog,
   incrementalBackupOfHook,

   // 还原备份数据
   restoreBackupDialogVisible,
   restoreBackupPassword,
   selectedFile,
   openRestoreBackupDialog,
   startUploadOfHook
   } = useBackup()

// 是否可以开始还原
const canRestore = computed(() => {
  return selectedFile.value && restoreBackupPassword.value && restoreBackupPassword.value.length >= 2
})

// 开始增量备份
const startIncrementalBackup = async () => {
  // 验证密码
  if (!validateIncrementalBackupPassword()) {
    return
  }
  
  try {
    // 启动加载状态
    incrementalBackupLoading.value = true
    incrementalBackupPasswordDialogVisible.value = false
    backupProgressVisible.value = true
    
    // 模拟备份进度
    simulateBackupProgress()
    
    // 执行实际备份操作
    await incrementalBackupOfHook()
    
    // 备份完成
    backupProgress.value = 100
    backupProgressText.value = '增量备份已完成！'
    
  } catch (error) {
    // 备份失败
    backupProgressText.value = '备份失败，请重试！'
    ElMessage.error('备份失败：' + (error instanceof Error ? error.message : String(error)))
  } finally {
    // 关闭加载状态
    incrementalBackupLoading.value = false
  }
}

// 模拟备份进度
const simulateBackupProgress = () => {
  backupProgress.value = 0
  let interval = setInterval(() => {
    if (backupProgress.value < 90) {
      backupProgress.value += Math.floor(Math.random() * 10) + 1
      
      // 更新进度提示文本
      if (backupProgress.value < 30) {
        backupProgressText.value = '正在读取文件...'
      } else if (backupProgress.value < 60) {
        backupProgressText.value = '正在压缩数据...'
      } else {
        backupProgressText.value = '正在写入备份...'
      }
    } else if (backupProgress.value < 100) {
      // 最后阶段慢一些
      backupProgress.value += 1
    } else {
      clearInterval(interval)
    }
  }, 300)
  
  // 确保定时器在一定时间后清除（防止内存泄漏）
  setTimeout(() => {
    clearInterval(interval)
  }, 30000)
}

// 验证密码长度 全量备份
const validateFullBackupPassword = () => {
  if (fullBackupPassword.value.length < 8) {
        ElMessage.error('密码安全性低：长度至少需要8位');
        return false
  }else{
    fullBackFlag.value = true
    return true
  }
};

// 验证密码长度 增量备份
const validateIncrementalBackupPassword = () => {
  if (incrementalBackupPassword.value.length < 2) {
        ElMessage.error('密码安全性低：长度至少需要8位');
        return false
  }else{
    incrementalBackupFlag.value = true
    return true
  }
};

// 选择备份文件
const handleFileChange = (file: any) => {
  // 当使用el-upload时，file对象直接是文件对象
  const uploadFile = file.raw || file
  
  if(!validateFile(uploadFile)) return
  
  selectedFile.value = uploadFile
  return false // 阻止自动上传
}

// 文件校验
const validateFile = (file) => {
  if (!file) return false
  
  // 文件类型校验
  if (!file.name.endsWith('.zip')) {
    ElMessage.error('仅支持ZIP格式的备份文件')
    return false
  }

  // 文件大小校验
  const maxBytes = 1024 * 1024 * 1024
  if (file.size > maxBytes) {
    ElMessage.error(`文件大小不能超过1GB`)
    return false
  }

  return true
}

// 开始还原备份
const startRestore = async () => {
  try {
    restoreLoading.value = true
    restoreBackupDialogVisible.value = false
    restoreProgressVisible.value = true
    // 模拟还原进度

    simulateRestoreProgress()
    // 执行实际还原操作
    const res = await startUploadOfHook()
    if(!res){
      restoreProgressVisible.value = false
    }
 
    // 还原完成
    restoreProgress.value = 100
    restoreProgressText.value = '备份还原已完成！'
    
  } catch (error) {
    // 还原失败
    restoreProgressText.value = '还原失败，请重试！'
    ElMessage.error('还原失败：' + (error instanceof Error ? error.message : String(error)))
  } finally {
    // 关闭加载状态
    restoreLoading.value = false
  }
}

// 模拟还原进度
const simulateRestoreProgress = () => {
  restoreProgress.value = 0
  let interval = setInterval(() => {
    if (restoreProgress.value < 85) {
      restoreProgress.value += Math.floor(Math.random() * 8) + 1
      
      // 更新进度提示文本
      if (restoreProgress.value < 20) {
        restoreProgressText.value = '正在验证备份文件...'
      } else if (restoreProgress.value < 40) {
        restoreProgressText.value = '正在解压备份文件...'
      } else if (restoreProgress.value < 60) {
        restoreProgressText.value = '正在还原数据...'
      } else {
        restoreProgressText.value = '正在验证数据完整性...'
      }
    } else if (restoreProgress.value < 100) {
      // 最后阶段慢一些
      restoreProgress.value += 1
    } else {
      clearInterval(interval)
    }
  }, 300)
  
  // 确保定时器在一定时间后清除（防止内存泄漏）
  setTimeout(() => {
    clearInterval(interval)
  }, 30000)
}



</script>

<style scoped lang="scss">
input[type="file"] {
  color: transparent;
}

.backup-container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px 10px;
}

.backup-card {
  margin-bottom: 20px;
  border-radius: 12px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
  overflow: hidden;
  transition: all 0.3s ease;
 
}

.backup-header {
  text-align: center;
  padding: 0 0 20px;
  margin-bottom: 20px;
  border-bottom: 1px solid #f0f0f0;
  
  .backup-title {
    margin: 0 0 8px;
    font-size: 24px;
    font-weight: 600;
    color: #303133;
  }
  
  .backup-subtitle {
    margin: 0;
    font-size: 14px;
    color: #909399;
  }
}

.action-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  margin-bottom: 25px;
  justify-content: center;
}

.action-button {
  flex: 1;
  min-width: 180px;
  height: auto !important;
  padding: 20px !important;
  transition: all 0.3s ease;
  border-radius: 8px !important;
  border: none !important;
  
  
  
  &.full-backup {
    background: linear-gradient(135deg, #409EFF, #1E88E5) !important;
  }
  
  &.incremental-backup {
    background: linear-gradient(135deg, #67C23A, #2E7D32) !important;
  }
  
  &.restore-backup {
    background: linear-gradient(135deg, #E6A23C, #F57C00) !important;
  }
}

.button-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  color: white;
}

.button-icon {
  font-size: 28px;
  margin-bottom: 10px;
}

.button-text {
  display: flex;
  flex-direction: column;
  text-align: center;
}

.button-title {
  font-size: 16px;
  font-weight: 500;
  margin-bottom: 4px;
}

.button-desc {
  font-size: 12px;
  opacity: 0.8;
}

.backup-footer {
  margin-top: 10px;
}

.backup-progress {
  padding: 20px 0;
  
  .progress-description {
    margin-top: 16px;
    color: #606266;
    text-align: center;
    font-size: 14px;
  }
}

.restore-form {
  padding: 0 10px;
  
  .el-form-item {
    margin-bottom: 20px;
  }
}

.file-upload-container {
  display: flex;
  flex-direction: column;
  gap: 16px;
  
  .backup-file-uploader {
    width: 100%;
  }
  
  .selected-file, .file-placeholder {
    display: flex;
    align-items: center;
    padding: 10px 16px;
    border-radius: 4px;
    background-color: #f8f9fa;
    
    .el-icon {
      margin-right: 10px;
      font-size: 20px;
    }
  }
  
  .selected-file {
    border: 1px solid #e1f3d8;
    background-color: #f0f9eb;
    
    .file-name {
      flex: 1;
      margin-right: 12px;
      font-weight: 500;
      color: #333;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    
    .file-size {
      font-size: 12px;
      color: #999;
    }
    
    .el-icon {
      color: #67c23a;
    }
  }
  
  .file-placeholder {
    border: 1px dashed #dcdfe6;
    color: #909399;
    
    .el-icon {
      color: #909399;
    }
  }
}

:deep(.el-button) {
  min-width: 100px;
  height: 40px;
}

:deep(.el-dialog__header) {
  margin-right: 0;
  border-bottom: 1px solid #f0f0f0;
  padding-bottom: 15px;
}

:deep(.el-dialog__footer) {
  border-top: 1px solid #f0f0f0;
  padding-top: 15px;
}

@media (max-width: 768px) {
  .action-buttons {
    flex-direction: column;
  }
  
  .action-button {
    width: 100%;
  }
  
  .button-content {
    flex-direction: row;
    justify-content: flex-start;
    
    .button-icon {
      margin-right: 16px;
      margin-bottom: 0;
    }
    
    .button-text {
      text-align: left;
    }
  }
  
  .file-upload-container {
    .selected-file, .file-placeholder {
      flex-direction: column;
      text-align: center;
      
      .el-icon {
        margin-right: 0;
        margin-bottom: 8px;
      }
    }
  }
}
</style>  
